import { ACTOR_TYPE, BActor, PointerActor } from "../";
import { Vector3 } from "@kitware/vtk.js/types";
import vtkRenderer from "@kitware/vtk.js/Rendering/Core/Renderer";
import vtkInteractorObserver from "@kitware/vtk.js/Rendering/Core/InteractorObserver.js";
//@ts-ignore
const { computeWorldToDisplay } = vtkInteractorObserver;

export interface LabelOptions {
  color?: string;
  fontSize?: number;
  text?: string;
  scale?: boolean; // * 文件标签是否跟随缩放
}

export class LabelActor extends BActor {
  createdBy = "default";
  instance = document.createElement("div");
  private _hide: PointerActor = new PointerActor([0, 0, 0], { radius: 1 });
  private _config: LabelOptions = {};
  readonly type: ACTOR_TYPE = ACTOR_TYPE.LABEL;
  private _start: Vector3 = [0, 0, 0];
  private _ref_renderer: vtkRenderer | null = null;
  private _height = 0;

  constructor(pos: Vector3, options: LabelOptions = {}) {
    super();
    this.instance.style.position = "absolute";
    this.instance.style.color = "red";
    this._config = options;
    this._start = pos;
    this._hide.position = [...pos];
    this._hide.visible = false;
    this.text("");
    this.initOptions();
  }

  initOptions() {
    if (this._config.text) {
      this.text(this._config.text);
    }
  }

  text(val: string) {
    this.instance.innerText = val;
  }

  update(scaleFactor: number = 1) {
    const [x, y, z] = this._hide.center;
    const r = computeWorldToDisplay(this._ref_renderer, x, y, z);
    this.updateScreenPosition([r[0], this._height - r[1]]);
    if(this._config.scale) {
      this.instance.style.transformOrigin = `top left`;
      this.instance.style.transform = `scale(${scaleFactor})`;
    }
  }

  mount(renderer: vtkRenderer, height: number) {
    this._ref_renderer = renderer;
    this._height = height;
    const r = computeWorldToDisplay(renderer, ...this._start);
    this.updateScreenPosition([r[0], height - r[1]]);
  }

  updateScreenPosition(pos: number[]) {
    this.instance.style.top = `${pos[1]}px`;
    this.instance.style.left = `${pos[0]}px`;
  }

  get flag() {
    return this._hide;
  }
}
